package net.towee.client.managers.impl;

import java.util.Date;
import java.util.List;

import net.towee.client.event.UserAccepted;
import net.towee.client.event.UserAcceptedHandler;
import net.towee.client.event.core.AccountIdentityUpdatedEvent;
import net.towee.client.event.core.AccountProfileUpdatedEvent;
import net.towee.client.managers.AccountHelper;
import net.towee.model.ProfileArea;
import net.towee.model.account.AccountData;
import net.towee.model.account.AccountGroup;
import net.towee.model.account.AccountPermission;
import net.towee.server.rpc.services.ToweeServiceAsync;

import com.google.common.base.Preconditions;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;

/**
 * Implementation of account helper interface
 * 
 * @author c58
 */
public class AccountHelperImpl implements AccountHelper {
	private final ToweeServiceAsync service;
	private final HandlerManager eventBus;
	private AccountData account;
	
	@Inject
	public AccountHelperImpl(ToweeServiceAsync service, HandlerManager eventBus) {
		this.service = service;
		this.eventBus = eventBus;
		
		eventBus.addHandler(UserAccepted.TYPE, new UserAcceptedHandler() {
			@Override
			public void onAccountAccepted(AccountData acc) {
				account = acc;
			}
		});
	}
	
	@Override
	public boolean hasPermissions(String groupId, AccountPermission... permissions) {
		Preconditions.checkNotNull(account, "account not initialized");
		return account.getGroups().isInGroups(groupId) && account.getGroups().getAccountGroup(groupId).getRole().hasPermissions(permissions);
	}

	@Override
	public List<ProfileArea> getProfileAreas() {
		Preconditions.checkNotNull(account, "account not initialized");
		return account.getProfile().getProfileAreas();
	}

	@Override
	public boolean isMemeberOfGroups(String... groupId) {
		Preconditions.checkNotNull(account, "account not initialized");
		return account.getGroups().isInGroups(groupId);
	}

	@Override
	public AccountGroup getAccountGroup(String groupId) {
		Preconditions.checkNotNull(account, "account not initialized");
		return account.getGroups().getAccountGroup(groupId);
	}

	@Override
	public AccountData getAccount() {
		return account;
	}

	@Override
	public void updateAccountProfile(final AsyncCallback<Boolean> handler) {
		service.updateAccountProfile(account.getProfile(), new AsyncCallback<Boolean>(){

			@Override
			public void onFailure(Throwable caught) {
				
			}

			@Override
			public void onSuccess(Boolean result) {
				// Fire an event
				eventBus.fireEvent(new AccountProfileUpdatedEvent(account.getProfile()));
				
				// Invoke handler
				handler.onSuccess(true);
			}
		});
	}

	@Override
	public void updateAccountIdentity(final AsyncCallback<Boolean> handler) {
		service.updateAccountIdentity(account.getAccountIdentity(), new AsyncCallback<Boolean>(){

			@Override
			public void onFailure(Throwable caught) {
				
			}

			@Override
			public void onSuccess(Boolean result) {
				// Fire an event
				eventBus.fireEvent(new AccountIdentityUpdatedEvent(account.getAccountIdentity()));
				
				// Invoke handler
				handler.onSuccess(true);
			}
		});
	}

	@Override
	public void putSetting(String key, String val, AsyncCallback<Boolean> handler) {
		// Put to local stored
		account.getSettingsContainer().putSetting(key, val);
		
		// Update in server
		service.putSetting(key, val, handler);
	}

	@Override
	public void updateSetings(AsyncCallback<Boolean> handler) {
		service.updateSettings(account.getSettingsContainer().getSettingsMap(), handler);
	}

	@Override
	public void rememberMe() {
		service.updateCookieId(new AsyncCallback<String>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(String result) {
				Date now = new Date();
				now.setYear( now.getYear()+1 );
				
				Cookies.removeCookie("__towee_rem_id");
				Cookies.setCookie("__towee_rem_id", result, now );
			}
		});
	}
}
